/*
    js原生运动组件
*/

//Mover构造函数
function Mover() {
    this.setting = {
        'times': 500,
        'fx': 'linear'
    }
}

//获取当前样式
Mover.prototype.getStyle = function(obj, attr) {
    return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr];
}

//获取当前时间
Mover.prototype.now = function() {
    return (new Date()).getTime();
}

//速度版运动框架
Mover.prototype.startMoveBySpeed = function(obj, json, fnEnd) {
    clearInterval(obj.timer);
    _this = this;
    obj.timer = setInterval(function() {
        obj.bStop = true;
        for (var attr in json) {
            var cur = 0;
            var speed = 0;
            if (attr === 'opacity') {
                cur = _this.getStyle(obj, attr);
                cur = Math.round(parseFloat(cur * 100));
            } else {
                cur = parseInt(_this.getStyle(obj, attr));
            }

            var speed = (json[attr] - cur) / 8;

            speed = speed ? Math.ceil(speed) : Math.floor(speed);

            if (cur !== json[attr]) {
                obj.bStop = false;
            }

            if (attr === 'opacity') {
                obj.style.opacity = (cur + speed) / 100;
                obj.style.filter = 'Alpha(opacity:' + (cur + speed) + ')';
            } else {
                obj.style[attr] = (cur + speed) + 'px';
            }
        }

        if (obj.bStop) {
            clearInterval(obj.timer);
            fnEnd && fnEnd.call(obj);
        }

    }, 20);
}

//时间版运动框架
Mover.prototype.startMoveByTime = function(obj, json, options, endFn) {
        //对于时间版框架来说，初始值b是固定的，所以写在定时器外面
        var _this = this;
        //默认设置
        extend(_this.setting, options);

        var iCur = {};
        //获取当前值
        for (attr in json) {
            iCur[attr] = 0;

            if (attr === 'opacity') {
                iCur[attr] = Math.round(parseFloat(_this.getStyle(obj, attr)) * 100);
            } else {
                iCur[attr] = parseInt(_this.getStyle(obj, attr));
            }

        };

        var iStartTime = _this.now();
        clearInterval(obj.timer);
        obj.timer = setInterval(function() {
            var iCurTime = _this.now();
            var t = _this.setting.times -
                Math.max(0, iStartTime - iCurTime + _this.setting.times);
            for (attr in json) {
                /*
                    Tween[fx]函数4个参数
                    t：current  time（当前时间）
                    b：beginning  value（初始值）
                    c： change  in  value（变化量）
                    d：duration（持续时间）
                    return  （目标点）   
                */
                var value = _this.Tween[_this.setting.fx](
                    t, //t  0~times
                    iCur[attr], //b
                    json[attr] - iCur[attr], //c
                    _this.setting.times //d
                );
                if (attr === 'opacity') {
                    obj.style[attr] = parseFloat(value / 100);
                    obj.style.filter = 'alpha(opacity:' + value + ')';
                } else {
                    obj.style[attr] = value + 'px';
                }

            }

            if (t === _this.setting.times) {
                clearInterval(obj.timer);
                endFn && endFn.call(obj);
            }
        }, 13);

    }
    //覆盖默认设置
function extend(child, father) {
    for (var attr in father) {
        child[attr] = father[attr];
    }
}
//Tween运动算法
Mover.prototype.Tween = {
    /*
        4个参数
        t：current  time（当前时间）
        b：beginning  value（初始值）
        c： change  in  value（变化量）
        d：duration（持续时间）
        return  （目标点）

    */

    linear: function(t, b, c, d) { //匀速
        return c * t / d + b;
    },
    easeIn: function(t, b, c, d) { //加速曲线
        return c * (t /= d) * t + b;
    },
    easeOut: function(t, b, c, d) { //减速曲线
        return -c * (t /= d) * (t - 2) + b;
    },
    easeBoth: function(t, b, c, d) { //加速减速曲线
        if ((t /= d / 2) < 1) {
            return c / 2 * t * t + b;
        }
        return -c / 2 * ((--t) * (t - 2) - 1) + b;
    },
    easeInStrong: function(t, b, c, d) { //加加速曲线
        return c * (t /= d) * t * t * t + b;
    },
    easeOutStrong: function(t, b, c, d) { //减减速曲线
        return -c * ((t = t / d - 1) * t * t * t - 1) + b;
    },
    easeBothStrong: function(t, b, c, d) { //加加速减减速曲线
        if ((t /= d / 2) < 1) {
            return c / 2 * t * t * t * t + b;
        }
        return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
    }
}
